package com.corpgovernment.permission.controller;

import com.corpgovernment.api.organization.model.bookingrelation.UidOrgIdEntry;
import com.corpgovernment.api.permission.vo.OrgAdminVo;
import com.corpgovernment.api.permission.vo.SearchUserRoleRequest;
import com.corpgovernment.api.supplier.permission.vo.DeleteUserRoleRequest;
import com.corpgovernment.common.base.BaseUserInfo;
import com.corpgovernment.common.base.Id;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.base.Page;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.operatelog.OperateLog;
import com.corpgovernment.common.operatelog.constant.OperateLogContant;
import com.corpgovernment.common.utils.BaseUtils;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.service.impl.OrganizationInfoServiceImpl;
import com.corpgovernment.permission.entity.db.MbRole;
import com.corpgovernment.permission.entity.db.MbUserRole;
import com.corpgovernment.permission.service.RoleService;
import com.corpgovernment.permission.service.UserRoleService;
import com.corpgovernment.permission.service.UserService;
import com.corpgovernment.permission.vo.UserRole;
import com.corpgovernment.redis.cache.RoleResourceManager;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.BooleanUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/userRole")
@Slf4j
public class UserRoleRest {
    @Autowired
    private UserService userService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private OrganizationInfoServiceImpl organizationInfoService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private RoleResourceManager manager;

    @GetMapping("/findAdminByOrgId")
    public JSONResult<List<OrgAdminVo>> findUserByOrg(@RequestParam("orgId") String orgId) {
        return JSONResult.success(userService.getConfiguredUserByOrgId(orgId));
    }

    /**
     * url: /corpApi/organization/userRole/getUser
     * http://10.5.119.87:9526/project/494/interface/api/11820
     */
    @PostMapping("/getUser")
    public JSONResult<Page<UserRoleInfo>> getUserRole(@RequestBody UserRolePageReq req, BaseUserInfo bui) {
        if (Objects.isNull(req)) {
            return JSONResult.errorMsg("参数不能为空");
        }
        Page page = userRoleService.pageQuery(req);

        if (CollectionUtils.isNotEmpty(page.getList())) {
            List<MbUserRole> mbUserRoleList = (List<MbUserRole>) page.getList();
            List<UserRoleInfo> userRoleInfoList = new ArrayList<>();
            mbUserRoleList.forEach(ur -> {
                UserRoleInfo urpr = new UserRoleInfo();
                urpr.setId(ur.getId());
                urpr.setUserId(ur.getUid());
                urpr.setRoleId(ur.getRoleId());
                urpr.setUserName(ur.getEmpName());
                urpr.setUserOrgId(ur.getOrgId());
                urpr.setUserOrgName(ur.getEmpOrgName());
                urpr.setRoleName(ur.getRoleName());
                urpr.setRoleOrgId(ur.getRoleOrgId());
                urpr.setRoleOrgName(ur.getRoleOrgName());
                urpr.setMobilePhone(ur.getEmpMobilePhone());
                urpr.setCountryCode(ur.getEmpAreaCode());
                urpr.setEmail(ur.getEmpEmail());
                urpr.setReconciliationEmail(ur.getReconciliationEmail());
                userRoleInfoList.add(urpr);
            });
            page.setList(userRoleInfoList);
        }
        return JSONResult.success(page);
    }

    /**
     * url: /corpApi/organization/userRole/batchSetUsersToRole
     * http://10.5.119.87:9526/project/494/interface/api/11828
     */
    @PostMapping("/batchSetUsersToRole")
    public JSONResult<?> batchSetUsersToRole(@RequestBody BatchSetReq req, BaseUserInfo bui) {
        if (!bui.getBgUser()) {
            if (req.getIdentities().stream().anyMatch(uoe -> StringUtils.isBlank(uoe.getOrgId()))) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_DONT_ACTION_ROLE);
            }
        }
        userRoleService.clearLeft(new HashSet<>(req.getIdentities()));
        userRoleService.batchAssociate(new HashSet<>(req.getIdentities()), Collections.singleton(req.getRoleId()));
        return JSONResult.ok();
    }

    /**
     * url: /corpApi/organization/userRole/deleteUserRole
     * http://10.5.119.87:9526/project/494/interface/api/11832
     */
    @PostMapping("/deleteUserRole")
    @OperateLog(OperateLogContant.USERROLEDEL)
    public JSONResult<?> deleteUserRole(@RequestBody Id<Long> id, BaseUserInfo bui) {
        if (!bui.getBgUser()) {
            MbRole mbRole = userRoleService.loadRole(id.getId());
            if (mbRole != null) {
                if (StringUtils.isBlank(mbRole.getOrgId())) {
                    throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_DONT_DEL_ROLE);
                }
            }
        }
        MbUserRole mbUserRole = userRoleService.selectById(id.getId());
        if (mbUserRole == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.ROLE_INFO_NULL);
        }
        userRoleService.delete(id.getId());
        manager.delUserRoleId(mbUserRole.getUid() + mbUserRole.getOrgId());
        return JSONResult.ok();
    }

	/**
	 * url: /corpApi/organization/userRole/searchCorpEmpIdentity http://10.5.119.87:9526/project/494/interface/api/12060
	 */
	@PostMapping("/searchCorpEmpIdentity")
	public JSONResult<List<UserInfo>> searchCorpEmpIdentity(@RequestBody SearchCorpEmpRequest request, BaseUserInfo bui) {
		List<String> corpIds = new ArrayList<>();
		if (!request.getIsBackground()) {
			request.setCorpId(BaseUtils.acquireOrgId(bui));
			if (StringUtils.isBlank(request.getCorpId())) {
				throw new CorpBusinessException(OrganizationResponseCodeEnum.CORP_ID_NULL);
			}
		}
		if (StringUtils.isNotBlank(request.getCorpId())) {
			corpIds = organizationInfoService.listRecentCompanyAllDepartmentByOrgId(request.getCorpId());
			corpIds.add(request.getCorpId());
		}
		List<UserRole> userRoles = BooleanUtils.isTrue(bui.getBgUser()) && BooleanUtils.isTrue(request.getIsBackground()) ? userRoleService.searchBgUser(request.getName()) : userRoleService.searchCorpEmp(corpIds, request.getName());
		userRoles = Optional.ofNullable(userRoles).orElse(new ArrayList<>());
		List<UserInfo> empList = userRoles.stream().map(ur -> {
			UserInfo uri = new UserInfo();
			BeanUtils.copyProperties(ur, uri);
            uri.setEmail(ur.getEmpEmail());
			return uri;
		}).collect(Collectors.toList());
		return JSONResult.success(empList);
	}

    /**
     * http://10.5.119.87:9526/project/494/interface/api/12314
     * 新增或者更新员工角色关系。员工关系编辑时，员工亦可修改。
     */
    @PostMapping("/insertOrUpdate")
    @Transactional
    @OperateLog(OperateLogContant.USERROLEADDOREDIT)
    public JSONResult<?> insertOrUpdate(@RequestBody @Valid InsertOrUpdate req, BaseUserInfo bui) {
        if (BooleanUtils.isNotTrue(bui.getBgUser()) && StringUtils.isBlank(req.getOrgId())) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.ORG_ID_NULL);
        }
        MbRole role = roleService.load(req.getRoleId());
        if (BooleanUtils.isTrue(role.getIsSystem())) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.SYSTEM_DONT_UPDATE);
        }
        userRoleService.clearLeft(Collections.singleton(new UidOrgIdEntry(req.getUid(), req.getOrgId())));
        userRoleService.insertOrUpdate(req.getId(), new UidOrgIdEntry(req.getUid(), req.getOrgId()), req.getRoleId());
        return JSONResult.ok();
    }

    /**
     * 搜索用户角色列表分页
     *
     * @param request
     * @return
     */
    @RequestMapping("/searcharUserRolePageList")
    public JSONResult searchUserRolePageList(@RequestBody SearchUserRoleRequest request) {
        return JSONResult.success(userRoleService.searchUserRole(request));
    }

    /**
     * 后台账号管理后台账号删除用户和角色关联关系
     *
     * @param request
     * @return
     */
    @RequestMapping("/deleteBgUser")
    public JSONResult deleteBgUser(@RequestBody DeleteUserRoleRequest request) {
        userRoleService.deleteUserRole(request.getStaffNumber());
        return JSONResult.ok();
    }


    public JSONResult<Long> findRoleIdByUidAndOrgId(@RequestParam("orgId") String orgId, @RequestParam("uid") String uid) {
        return userRoleService.findRoleIdByUidAndOrgId(orgId, uid);
    }

    @Data
    public static class UserInfo {
        @JsonProperty("uid")
        private String userId;
        private String countryCode;
        private String mobilePhone;
        private Long roleId;
        private String roleName;
        @JsonProperty("name")
        private String userName;
        @JsonProperty("orgId")
        private String userOrgId;
        @JsonProperty("orgName")
        private String userOrgName;
        private String email;
    }

    @Data
	public static class SearchCorpEmpRequest {
		private String corpId;
		private String name;
		private Boolean isBackground;
	}

	@Data
    public static class BatchSetReq {
        private List<UidOrgIdEntry> identities;
        private Long roleId;
    }

    @Data
    public static class InsertOrUpdate {
        private Long id;
        @NotNull(message = "roleId不能为空")
        private Long roleId;
        @NotBlank(message = "uid不能为空")
        private String uid;
        private String orgId;
    }

    @Data
    public static class UserRoleInfo {
        private Long id;
        @JsonProperty("uid")
        private String userId;
        private Long roleId;
        @JsonProperty("name")
        private String userName;
        @JsonProperty("orgId")
        private String userOrgId;
        @JsonProperty("orgName")
        private String userOrgName;
        private String roleName;
        private String roleOrgId;
        private String roleOrgName;
        private String mobilePhone;
        private String countryCode;
        private String email;
        private Boolean reconciliationEmail;
    }

    @Data
    public static class UserRolePageReq extends Page {
        private Long roleId;
        @JsonProperty("name")
        private String empName;

        private String roleOrgId;

        private Boolean isBackground;

        private String corpId;
    }
}
